using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace Toon.Controls
{
	public class VerticalStackingPanel : Panel
	{
		public static readonly DependencyProperty MaxColumnsProperty = DependencyProperty.Register("MaxColumns", typeof(int), typeof(VerticalStackingPanel), new PropertyMetadata(2, OnMaxColumnsChanged));

		private static void OnMaxColumnsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
		{
			VerticalStackingPanel verticalStackingPanel = o as VerticalStackingPanel;
			if (verticalStackingPanel != null)
				verticalStackingPanel.OnMaxColumnsChanged((int)e.OldValue, (int)e.NewValue);
		}

		protected virtual void OnMaxColumnsChanged(int oldValue, int newValue)
		{
			// TODO: Add your property changed side-effects. Descendants can override as well.
		}

		public int MaxColumns
		{
			get { return (int)GetValue(MaxColumnsProperty); }
			set { SetValue(MaxColumnsProperty, value); }
		}


		protected override Size MeasureOverride(Size availableSize)
		{
			var workingSize = availableSize;
			if (double.IsInfinity(workingSize.Height))
				workingSize.Height = 1000;
			if (double.IsInfinity(workingSize.Width))
				workingSize.Width = 1000;


			var childSize = new Size(workingSize.Width / MaxColumns, workingSize.Height);

			var columns = new Double[MaxColumns];

			foreach (FrameworkElement child in Children)
			{
				child.Measure(childSize);

				var nextColumn = 0;
				for (int i = 0; i < columns.Length; i++)
				{
					if (columns[i] < columns[nextColumn])
						nextColumn = i;
				}

				columns[nextColumn] += child.DesiredSize.Height;
			}

			var maxHeigth = columns.Max();

			return new Size(workingSize.Width, maxHeigth);
		}

		protected override Size ArrangeOverride(Size finalSize)
		{
			var childWidth = finalSize.Width / MaxColumns;

			var columnHeigths = new Double[MaxColumns];
			var columnWidths = new Double[MaxColumns];

			foreach (FrameworkElement child in Children)
			{
				var nextColumn = 0;
				for (int i = 0; i < columnHeigths.Length; i++)
				{
					if (columnHeigths[i] < columnHeigths[nextColumn])
						nextColumn = i;
				}
				columnHeigths[nextColumn] += child.DesiredSize.Height;
				columnWidths[nextColumn] = Math.Max(columnWidths[nextColumn], child.DesiredSize.Width);

			}

			columnHeigths = new Double[MaxColumns];

			foreach (FrameworkElement child in Children)
			{

				var nextColumn = 0;
				var xOffset = 0.0;

				for (int i = 0; i < columnHeigths.Length; i++)
				{
					if (columnHeigths[i] < columnHeigths[nextColumn])
						nextColumn = i;
				}
				for (int i = 0; i < nextColumn; i++)
				{
					xOffset += columnWidths[i];
				}

				child.Arrange(new Rect(xOffset, columnHeigths[nextColumn], child.DesiredSize.Width, child.DesiredSize.Height));

				columnHeigths[nextColumn] += child.DesiredSize.Height;

			}
			var maxHeigth = columnHeigths.Max();

			return new Size(finalSize.Width, maxHeigth);
		}

	}
}
